package com.sign.common.util.threadpool;

import java.util.List;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

/**
 * @Author 513422479@qq.com
 * Date on 2020/5/28  21:53
 */
public final class MyThreadPoolUtils {

    private  static  final Logger log=  Logger.getLogger("sa");

    private  static  volatile  ThreadPoolUtils instance =null;

    private  final  static int COMMON_THREAD_POOL_NUM=30;

    private final static  String COMMON_THREAD_POOL_NAME="CommonThreadPool";

    private  static  volatile  ThreadPoolUtils coreInstance =null;

    private  final  static int CORE_THREAD_POOL_NUM=15;

    private final static  String CORE_THREAD_POOL_NAME="CoreThreadPool";

    private  MyThreadPoolUtils(){}


    /**
     * 常规线程池，用于打印日志，提交测试任务等不必等待任务执行完成的不怕阻塞的操作
     * @return
     */
    public  static  ThreadPoolUtils getInstance(){

        if(null== instance){
            synchronized (MyThreadPoolUtils.class){
                if(null== instance){
                    instance=
                            getInnerInstance(COMMON_THREAD_POOL_NUM,COMMON_THREAD_POOL_NAME);
                }
            }
            return instance;
        }
        return  getInnerInstance(COMMON_THREAD_POOL_NUM,COMMON_THREAD_POOL_NAME);

    }

    /**
     * 核心线程池，用于性能敏感比如并发查询等操作，不可以提交长时间操作的阻塞任务
     * @return
     */
    public static   ThreadPoolUtils getCoreInstance(){
        if(null== coreInstance){
            synchronized (MyThreadPoolUtils.class){
                if(null== coreInstance){
                    coreInstance=
                            getInnerInstance(CORE_THREAD_POOL_NUM,CORE_THREAD_POOL_NAME);
                }
            }
            return coreInstance;
        }
        return  getInnerInstance(CORE_THREAD_POOL_NUM,CORE_THREAD_POOL_NAME);
    }
    
    private  static  ThreadPoolUtils  getInnerInstance(int threadNum,String poolName){
        return  new ThreadPoolUtils(threadNum,poolName);
    }

    private  static  ThreadPoolUtils  getInnerInstance(ThreadPoolUtils innerInstance,
                                                       int threadNum,String poolName){
        if(needRebuildPool(innerInstance)){
            synchronized (MyThreadPoolUtils.class){
                if (needRebuildPool(innerInstance)){
                    innerInstance=getInnerInstance(threadNum,poolName);
                }
            }
        }

        return innerInstance;
    }

    private static boolean needRebuildPool(ThreadPoolUtils innerInstance) {
        return innerInstance==null || innerInstance.getExecutor()==null ||
                innerInstance.getExecutor().isShutdown();
    }

    public static  void waitFuturesDone(List<Future<?>> futures){
        waitFuturesDone(futures,5L,TimeUnit.SECONDS);
    }

    public static void waitFuturesDone(List<Future<?>> futures, long timeOut, TimeUnit unit) {
        if(futures == null){
            return;
        }
        for (Future future: futures) {
            if(future == null){
                continue;
            }
            try {
                future.get(timeOut, unit);
            }catch (Throwable e){
                System.out.println(e.toString());
//                throw  new ApplicationRuntimeException(e);
            }
        }
    }

}
